package com.whosly.mysql.protocol.packet.impl;

import com.whosly.mysql.protocol.jdbc.MySQLMessage;
import com.whosly.mysql.protocol.packet.util.NettyBufferUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

/**
 * 1. MY_COM_RDS_AUTH_AND_SWITCH <br>
 * 29, Username, 0, clientip, 0, size(scramble), scramble, 0, size(authdata),
 * authdata <br>
 * 2. MY_COM_RDS_AUTH <br>
 * 29, Username, 0, clientip, 0, size(scramble), scramble, 0, size(authdata),
 * authdata
 *
 * @author fengyang
 * @date 2023/7/20 下午3:56
 * @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
 */
public class RdsAuthCommandPacket extends CommandPacket {
    public String username;
    public String clientIp;
    public byte[] scramble;
    public byte[] authdata;
    public boolean isUserSwitch;

    @Override
    public ByteBuf writeBuf()
    {
        ByteBuf buffer = Unpooled.buffer(calcPacketSize());

        return writeBuf(buffer);
    }

    @Override
    public ByteBuf writeBuf(ByteBuf buffer)
    {
        NettyBufferUtil.writeUB3(buffer, buffer.capacity());
        buffer.writeByte(getPackId());

        writeBody(buffer);

        return buffer;
    }

    private void writeBody(ByteBuf buffer){
        buffer.writeByte(this.getCmd());

        if (username != null && clientIp != null && scramble != null && authdata != null) {
            NettyBufferUtil.writeWithLength(buffer, parseBytes(username));
            NettyBufferUtil.writeWithLength(buffer, parseBytes(clientIp));

            buffer.writeByte((byte) scramble.length);
            buffer.writeBytes(scramble);

            buffer.writeByte((byte) 0);
            buffer.writeByte((byte) authdata.length);
            buffer.writeBytes(authdata);
        }
    }

    @Override
    public void read(byte[] bodyBytes)
    {
        super.read(bodyBytes);
    }

    @Override
    protected void readBody(byte[] bodyBytes)
    {
        readBody(bodyBytes, null);
    }

    private void readBody(byte[] bodyBytes, String charset) {
        MySQLMessage mm = new MySQLMessage(bodyBytes);

        setCmd(mm.read());
        if (getCmd() == MY_COM_RDS_AUTH_AND_SWITCH) {
            this.isUserSwitch = true;
        } else {
            this.isUserSwitch = false;
        }

        this.username = charset == null ? mm.readStringWithLength() : mm.readStringWithLength(charset);
        this.clientIp = charset == null ? mm.readStringWithLength() : mm.readStringWithLength(charset);

        byte scambleSize = mm.read();
        this.scramble = mm.readBytes(scambleSize);

        //skip 0
        mm.read();

        int authdataSize = mm.read();
        this.authdata = mm.readBytes(authdataSize);
    }

    @Override
    public int calcPacketSize() {
        int packLength = super.calcPacketSize();

        if (username != null && clientIp != null && scramble != null && authdata != null) {
            int newPacketLength = getPacketLength();
            newPacketLength += (username.getBytes().length + 1);
            newPacketLength += (clientIp.getBytes().length + 1);
            newPacketLength += (scramble.length + 1);
            newPacketLength += 1;
            newPacketLength += (authdata.length + 1);

            setArgs(newPacketLength, getPackId());
        }

        return packLength;
    }

    @Override
    public String toString() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("[Length=").append(StringFillFormat.format(getPacketLength(), 4));
        stringBuilder.append(", PacketId=").append(StringFillFormat.format(getPackId(), 2));
        stringBuilder.append(", Command=").append(StringFillFormat.format(getCmd(), 2));
        stringBuilder.append(", Username=").append(username).append(",");
        stringBuilder.append(", ClientIp=").append(clientIp).append("]");
        return stringBuilder.toString();
    }

}
